#if !defined(LOG_H)
#define LOG_H

#include <cstring>
#include <iostream>
#include <pthread.h>
#include <stdarg.h>
#include <stdio.h>

#include "block_queue.h"

class Log
{
private:
    /// @brief 路径名
    char dir_name[128];
    /// @brief LOG文件名
    char log_name[128];
    /// @brief 日志最大行数
    int m_split_lines;
    /// @brief 日志缓冲区大小
    int m_log_buf_size;
    /// @brief 日志行数记录
    long long m_count;
    /// @brief 当前日期
    int m_today;

    /// @brief LOG文件指针
    FILE *m_fp;
    /// @brief 输出内容
    char *m_buf;
    /// @brief 阻塞队列
    block_queue<std::string> *m_log_queue;
    /// @brief 是否同步标志
    bool m_is_async;
    /// @brief 互斥锁
    locker m_mutex;

public:
    /// @brief 获取唯一实例（懒汉模式）
    /// @return
    static Log *getInstance()
    {
        static Log instance;
        return &instance;
    }

    /// @brief 写入日志（异步）
    /// @param args
    /// @return
    static void *flush_log_thread(void *args)
    {
        Log::getInstance()->async_write_log();
        return NULL;
    }

    /// @brief 初始化实例
    /// @param fileName 日志文件名
    /// @param logBufSize 日志缓冲区大小
    /// @param splitLines 最大行数
    /// @param maxQueueSize 最长日志条队列
    /// @return
    bool init(const char *fileName, int logBufSize = 8192, int splitLines = 5000000, int maxQueueSize = 0);

    /// @brief 输出内容按标准格式整理
    /// @param level
    /// @param format
    /// @param
    void write_log(int level, const char *format, ...);

    /// @brief 强制刷新缓冲区
    /// @param
    void flush(void);

private:
    Log();
    virtual ~Log();

    /// @brief 异步写日志
    /// @return
    void *async_write_log();
};

#define LOG_DEBUG(format, ...) Log::getInstance()->write_log(0, format, ##__VA_ARGS__)
#define LOG_INFO(format, ...) Log::getInstance()->write_log(1, format, ##__VA_ARGS__)
#define LOG_WARN(format, ...) Log::getInstance()->write_log(2, format, ##__VA_ARGS__)
#define LOG_ERROR(format, ...) Log::getInstance()->write_log(3, format, ##__VA_ARGS__)

#endif // LOG_H
